/**
  ******************************************************************************
  * File Name          : terminal.c
  * Description        : Code for terminal applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tskcfg.h"
#include "bsp.h"
#include "eeprom.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xc.h"


#define TTY_RXBUF_MAXLEN           128
#define TTYRECV_QUE_LENGTH         3
#define TTYRECV_QUE_ITEMSIZE       sizeof(tty_recvbuftype)

typedef enum
{
	TTY_HEADER1  = 0u,
	TTY_HEADER2,
	TTY_PAYLOAD,
	TTY_0A,
}tty_recvstattype;

typedef struct
{
	char buf[TTY_RXBUF_MAXLEN];
	uint8_t len;
}tty_recvbuftype;

typedef struct
{
	tty_recvstattype stat;
}tty_recvctrltype;

QueueHandle_t        ttyrecv_qhd;
static StaticQueue_t ttyrecv_stru;
static uint8_t       ttyrecv_area[ TTYRECV_QUE_LENGTH * TTYRECV_QUE_ITEMSIZE ];

TaskHandle_t xTerminal_Thd = NULL;
StaticTask_t xTerminal_Tcb;
StackType_t  xTerminal_Stk[ TTY_STACK_SIZE ];

static tty_recvctrltype   tty_rcvctrl;
static tty_recvbuftype    tty_isrbuf;
tty_recvbuftype    tty_rcvbuf;

static void cmd_act(const char *buf)
{
  int val;
  Xc_ActionCmdType scmd;
  
  val = atoi(buf);
  if(Xc_RxCmd_Qhd != NULL)
  {
    scmd.cmd = XC_ACTCMD_ACTION;
    scmd.dat = val;
    xQueueSend(Xc_RxCmd_Qhd, &scmd, 0);
  }
}

static void cmd_ctp(const char *buf)
{
  int val;
  
  val = atoi(buf);
  
  printf("CTP:%d\r\n", Xc_CodeToPercent(val));
}

static void cmd_ptc(const char *buf)
{
  int val;
  
  val = atoi(buf);
  
  printf("PTC:%d\r\n", Xc_PercentToCode(val));
}

void vTerminal_Task( void * pvParameters )
{
	const char *p;
	ttyrecv_qhd = xQueueCreateStatic(TTYRECV_QUE_LENGTH,
	                                 TTYRECV_QUE_ITEMSIZE,
	                                 ttyrecv_area,
	                                 &ttyrecv_stru);
	while(1)
	{
		if(xQueueReceive(ttyrecv_qhd, &tty_rcvbuf, portMAX_DELAY) == pdTRUE)
		{
      p = strstr( tty_rcvbuf.buf, "RESET");
			if( p != NULL)
			{
        if(Xc_RxCmd_Qhd != NULL)
        {
          xQueueSend(Xc_RxCmd_Qhd, &Xc_CmdReset, 0);
        }
			}
      
      p = strstr( tty_rcvbuf.buf, "ACT:");
			if( p != NULL)
			{
        cmd_act(p+4);
			}
      
      p = strstr( tty_rcvbuf.buf, "CTP:");
			if( p != NULL)
			{
        cmd_ctp(p+4);
			}
      
      p = strstr( tty_rcvbuf.buf, "PTC:");
			if( p != NULL)
			{
        cmd_ptc(p+4);
			}
      
      p = strstr( tty_rcvbuf.buf, "MUL");
			if( p != NULL)
			{
        if(Xc_RxCmd_Qhd != NULL)
        {
          xQueueSend(Xc_RxCmd_Qhd, &Xc_CmdMarkUpLimit, 0);
        }
			}
      
			p = strstr( tty_rcvbuf.buf, "TIME");
			if( p != NULL)
			{
				_printf("%04d-%02d-%02d %02d:%02d:%02d\r\n", Sys_Runtime.year+2000,\
																										Sys_Runtime.month,\
																										Sys_Runtime.day,\
																										Sys_Runtime.hour,\
																										Sys_Runtime.minute,\
																										Sys_Runtime.second);
			}
		}
	}
}

void Terminal_RecvIsr(uint8_t dat)
{
	static uint32_t count;
	
	switch(tty_rcvctrl.stat)
	{
		case TTY_HEADER1:
			if(dat == ';')
			{
				tty_rcvctrl.stat = TTY_HEADER2;
			}
			break;
		
		case TTY_HEADER2:
			if(dat == ';')
			{
				tty_rcvctrl.stat = TTY_PAYLOAD;
				count = 0;
			}
			else
			{
				tty_rcvctrl.stat = TTY_HEADER1;
			}
			break;
		
		case TTY_PAYLOAD:
			if(dat == 0x0du)
			{
				tty_rcvctrl.stat = TTY_0A;
			}
			else
			{
				tty_isrbuf.buf[count++] = dat;
				if(count > (TTY_RXBUF_MAXLEN-4))
				{
					tty_rcvctrl.stat = TTY_HEADER1;
				}
			}
			break;
		
		case TTY_0A:
			if(dat == 0x0au)
			{
				tty_isrbuf.buf[count] = 0;
				tty_isrbuf.len = count;
				if(ttyrecv_qhd != NULL)
				{
					xQueueSendFromISR(ttyrecv_qhd, &tty_isrbuf, NULL);
				}
			}
			tty_rcvctrl.stat = TTY_HEADER1;
			break;
		
		default:
			tty_rcvctrl.stat = TTY_HEADER1;
			break;
	}
}

void Terminal_BreakIsr(void)
{
	tty_rcvctrl.stat = TTY_HEADER1;
}
